Conversation
SalamanderPacketConn and GeckoPacketConn embed the net.PacketConn interface, which hides SetReadBuffer/SetWriteBuffer. quic-go's type assertion in setReceiveBuffer/setSendBuffer then fails and the socket keeps net.core.rmem_default instead of the 8 MB it asks for. Re-expose both methods, resolving the underlying conn with common.Cast as hysteria/hop.go does.
a0d0808 to
62f707c
Compare
7a0d5dc to
497364e
Compare
|
Closing: this change no longer has any effect on current code. Since SagerNet/quic-go a7bffd4a ("Probe socket capabilities through syscall.Conn", first shipped in v0.61.0-sing-box-mod.2, 2026-08-06), The remaining gap is on the server side: |
SalamanderPacketConnandGeckoPacketConnembed thenet.PacketConninterface, soSetReadBuffer/SetWriteBufferare not promoted. quic-go gives up on its first assertion:No syscall is ever issued, so with
obfsconfigured the socket stays atnet.core.rmem_default(212992, ~146 packets of depth) instead of quic-go's 8 MB and overflows in bursts. Withoutobfsthe conn arrives as a bare*net.UDPConnand sizing works, which is why the symptom only shows with obfuscation on. Upstream hysteria forwards these methods for the same reason (extras/obfs/conn.go).Both are re-exposed through
common.Cast, which followsUpstream()so client-side wrappers such asbufio.UnbindPacketConnare resolved; this mirrorshysteria/hop.go.SyscallConnis deliberately left out:wrapConnaborts listen/dial when it errors, and the client may run over a non-UDP conn through a detour dialer.Reproducing quic-go's assertions against a real socket:
SetReadBufferOOBCapablePacketConn*net.UDPConn(reference)OOBCapablePacketConnstays false, so quic-go keeps usingReadFrom/WriteToand never bypasses deobfuscation. Over a non-UDP conn both returnos.ErrInvalid, whichwrapConndiscards.Builds and vets clean on linux, android, windows, darwin and freebsd;
gofumpt,gofmt -sandgcireport no changes.The
salamander.gohalf applies unchanged tomainif you want it on the 1.13.x line.